/*
 *  Copyright 2019-2023 oyun
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.oyun.modules.medicine.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oyun.modules.medicine.domain.*;
import com.oyun.modules.medicine.domain.vo.IllnessQueryCriteria;
import com.oyun.modules.medicine.mapper.*;
import com.oyun.modules.medicine.service.IllnessService;
import com.oyun.segment.convert.itmd.IntermediateCodeUtils;
import com.oyun.utils.FileUtil;
import com.oyun.utils.PageResult;
import com.oyun.utils.PageUtil;
import com.oyun.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author oyun
 * @description 服务实现
 * @date 2024-04-29
 **/
@Service
@RequiredArgsConstructor
public class IllnessServiceImpl extends ServiceImpl<IllnessMapper, Illness> implements IllnessService {

    private final IllnessMapper illnessMapper;

    private final AdministraticeIllnessMapper administraticeIllnessMapper;

    private final IllnessHpMapper illnessHpMapper;

    private final DoctorMapper doctorMapper;

    private final IllnessExportMapper illnessExportMapper;

    private final HospitalMapper hospitalMapper;

    @Override
    public PageResult<Illness> queryAll(IllnessQueryCriteria criteria, Page<Object> page) {
        if (StringUtils.isNotEmpty(criteria.getName())) {
            criteria.setReplaceAll(IntermediateCodeUtils.mn2Code(criteria.getName()).replaceAll("-", " -"));
        }
        IPage<Illness> all = illnessMapper.findAll(criteria, page);
        Acquire(all.getRecords());
        return PageUtil.toPage(all);
    }

    @Override
    public List<Illness> queryAll(IllnessQueryCriteria criteria) {
        return illnessMapper.findAll(criteria);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Illness resources) {
        convertCode(resources);
        save(resources);
        insertOrUpdate(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Illness resources) {
        Illness illness = getById(resources.getId());
        illness.copy(resources);
        convertCode(illness);
        saveOrUpdate(illness);
        //根据疾病id修改科室
        LambdaQueryWrapper<AdministraticeIllness> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdministraticeIllness::getIllnessId, resources.getId());
        List<AdministraticeIllness> list = administraticeIllnessMapper.selectList(wrapper);
        for (AdministraticeIllness administraticeIllness : list) {
            administraticeIllness.setStatus(0);
            administraticeIllnessMapper.updateById(administraticeIllness);
        }
        LambdaQueryWrapper<IllnessHp> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(IllnessHp::getIllnessId,resources.getId());
        List<IllnessHp> illnesses = illnessHpMapper.selectList(wrapper1);
        for (IllnessHp illnessHp : illnesses) {
            illnessHp.setStatus(0);
            illnessHpMapper.updateById(illnessHp);
        }
        LambdaQueryWrapper<IllnessExport> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(IllnessExport::getIllnessId,resources.getId());
        List<IllnessExport> selectList = illnessExportMapper.selectList(wrapper2);
        for (IllnessExport export : selectList) {
            export.setStatus(0);
            illnessExportMapper.updateById(export);
        }
        insertOrUpdate(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        removeBatchByIds(ids);
        LambdaQueryWrapper<AdministraticeIllness> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(AdministraticeIllness::getIllnessId, ids).eq(AdministraticeIllness::getStatus,1);
        List<AdministraticeIllness> list = administraticeIllnessMapper.selectList(wrapper);
        for (AdministraticeIllness administraticeIllness : list) {
            administraticeIllness.setStatus(0);
            administraticeIllnessMapper.updateById(administraticeIllness);
        }
        LambdaQueryWrapper<IllnessHp> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.in(IllnessHp::getIllnessId,ids).eq(IllnessHp::getStatus,1);
        List<IllnessHp> illnesses = illnessHpMapper.selectList(wrapper1);
        for (IllnessHp illnessHp : illnesses) {
            illnessHp.setStatus(0);
            illnessHpMapper.updateById(illnessHp);
        }
        LambdaQueryWrapper<IllnessExport> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.in(IllnessExport::getIllnessId,ids).eq(IllnessExport::getStatus,1);
        List<IllnessExport> selectList = illnessExportMapper.selectList(wrapper2);
        for (IllnessExport export : selectList) {
            export.setStatus(0);
            illnessExportMapper.updateById(export);
        }
    }

    @Override
    public void download(List<Illness> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Illness illness : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("医院id", illness.getHpId());
            map.put("分类（字典）", illness.getType());
            map.put("蒙语疾病名称", illness.getMnName());
            map.put(" mnNameCode", illness.getMnNameCode());
            map.put(" zhName", illness.getZhName());
            map.put("蒙语疾病定义", illness.getMnDefinition());
            map.put(" zhDefinition", illness.getZhDefinition());
            map.put("蒙语诊断", illness.getMnDiagnosis());
            map.put(" mnDiagnosisCode", illness.getMnDiagnosisCode());
            map.put(" zhDiagnosis", illness.getZhDiagnosis());
            map.put("蒙语病因与病机", illness.getMnPathogenesis());
            map.put(" mnPathogenesisCode", illness.getMnPathogenesisCode());
            map.put(" zhPathogenesis", illness.getZhPathogenesis());
            map.put("蒙语疾病临床表现", illness.getMnClinical());
            map.put(" mnClinicalCode", illness.getMnClinicalCode());
            map.put(" zhClinical", illness.getZhClinical());
            map.put("蒙语治疗重点", illness.getMnTreatment());
            map.put(" mnTreatmentCode", illness.getMnTreatmentCode());
            map.put(" zhTreatment", illness.getZhTreatment());
            map.put("蒙语治疗原则", illness.getMnPrinciple());
            map.put(" mnPrincipleCode", illness.getMnPrincipleCode());
            map.put(" zhPrinciple", illness.getZhPrinciple());
            map.put("蒙语治疗方法", illness.getMnTreatmentMethod());
            map.put(" mnTreatmentMethodCode", illness.getMnTreatmentMethodCode());
            map.put(" zhTreatmentMethod", illness.getZhTreatmentMethod());
            map.put("蒙语护理与预防", illness.getMnPrevention());
            map.put(" mnPreventionCode", illness.getMnPreventionCode());
            map.put(" zhPrevention", illness.getZhPrevention());
            map.put("传染性(字典)", illness.getTransmissibility());
            map.put("严重性(字典)", illness.getSeriousness());
            map.put("治愈率", illness.getRecoveryRate());
            map.put("蒙语科学研究", illness.getMnScientificResearch());
            map.put(" zhScientificResearch", illness.getZhScientificResearch());
            map.put(" createBy", illness.getCreateBy());
            map.put(" createTime", illness.getCreateTime());
            map.put(" updateBy", illness.getUpdateBy());
            map.put(" updateTime", illness.getUpdateTime());
            map.put(" status", illness.getStatus());
            map.put(" remark", illness.getRemark());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<Doctor> getExpert(List<Long> ids) {
        LambdaQueryWrapper<Doctor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Doctor::getExpert,1).in(Doctor::getAdministrativeId,ids);
        return doctorMapper.selectList(wrapper);
    }

    @Override
    public List<Illness>  getList() {
        LambdaQueryWrapper<Illness> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Illness::getStatus,1);
        return illnessMapper.selectList(wrapper);
    }

    @Override
    public Object getByName(String name) {
        String replaceAll = IntermediateCodeUtils.mn2Code(name).replaceAll("-", " -");
        LambdaQueryWrapper<Illness> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Illness::getZhName,name).or().like(Illness::getMnNameCode,replaceAll);
        List<Illness> illnesses = illnessMapper.selectList(wrapper);
        Acquire(illnesses);
        return illnesses;
    }

    private void insertOrUpdate(Illness resources) {
        for (Long officeId : resources.getOfficeId()) {
            AdministraticeIllness administraticeIllness = new AdministraticeIllness();
            administraticeIllness.setAdministraticeId(officeId);//科室id
            administraticeIllness.setIllnessId(resources.getId());//疾病id
            administraticeIllness.setStatus(1);
            administraticeIllnessMapper.insert(administraticeIllness);
        }
        for (Long illnessHpId : resources.getRecommendHp()) {
            IllnessHp illnessHp = new IllnessHp();
            illnessHp.setIllnessId(resources.getId());//疾病id
            illnessHp.setHospitalId(illnessHpId);//推荐医院id
            illnessHp.setStatus(1);
            illnessHpMapper.insert(illnessHp);
        }
        for (Long expertId: resources.getExpertIds()){
            IllnessExport export = new IllnessExport();
            export.setIllnessId(resources.getId());
            export.setExportId(expertId);
            export.setStatus(1);
            illnessExportMapper.insert(export);
        }
    }

    private void convertCode(Illness illness){
        illness.setMnNameCode(IntermediateCodeUtils.mn2Code(illness.getMnName()).replaceAll("-", " -"));
        illness.setMnDiagnosisCode(IntermediateCodeUtils.mn2Code(illness.getMnDiagnosis()).replaceAll("-", " -"));
        illness.setMnPathogenesisCode(IntermediateCodeUtils.mn2Code(illness.getMnPathogenesis()).replaceAll("-", " -"));
        illness.setMnClinicalCode(IntermediateCodeUtils.mn2Code(illness.getMnClinical()).replaceAll("-", " -"));
        illness.setMnTreatmentCode(IntermediateCodeUtils.mn2Code(illness.getMnTreatment()).replaceAll("-", " -"));
        illness.setMnPrincipleCode(IntermediateCodeUtils.mn2Code(illness.getMnPrinciple()).replaceAll("-", " -"));
        illness.setMnTreatmentMethodCode(IntermediateCodeUtils.mn2Code(illness.getMnTreatmentMethod()).replaceAll("-", " -"));
        illness.setMnPreventionCode(IntermediateCodeUtils.mn2Code(illness.getMnPrevention()).replaceAll("-", " -"));
    }

    private void Acquire(List<Illness> illnessList){
        for (Illness illness : illnessList){
            LambdaQueryWrapper<AdministraticeIllness> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(AdministraticeIllness::getIllnessId,illness.getId()).eq(AdministraticeIllness::getStatus,1);
            List<AdministraticeIllness> list = administraticeIllnessMapper.selectList(wrapper);
            List<Long> collect = list.stream().map(AdministraticeIllness::getAdministraticeId).collect(Collectors.toList());
            illness.setOfficeId(collect);

            LambdaQueryWrapper<IllnessHp> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(IllnessHp::getIllnessId,illness.getId()).eq(IllnessHp::getStatus,1);
            List<IllnessHp> list1 = illnessHpMapper.selectList(wrapper1);
            List<Long> collect1 = list1.stream().map(IllnessHp::getHospitalId).collect(Collectors.toList());
            illness.setRecommendHp(collect1);

            LambdaQueryWrapper<IllnessExport> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.eq(IllnessExport::getIllnessId,illness.getId()).eq(IllnessExport::getStatus,1);
            List<IllnessExport> list2 = illnessExportMapper.selectList(wrapper2);
            List<Long> collect2 = list2.stream().map(IllnessExport::getExportId).collect(Collectors.toList());
            illness.setExpertIds(collect2);

            LambdaQueryWrapper<Hospital> wrapper3 = new LambdaQueryWrapper<>();
            wrapper3.eq(Hospital::getId,illness.getHpId());
            Hospital hospital = hospitalMapper.selectOne(wrapper3);
            if (hospital!= null) illness.setHpName(hospital.getMnName());
        }
    }
}
